#include "psam_card.h"

/**
  * 功能:  计算密钥
  * 
  *
  * 返回值:
  * 	   
  **/

s32 psam_card_get_key(reader_op *reader, u8 key_flag, u8 key_id)
{
	s32 ret;
	card_data send;

	if (!reader) {
		debug("psam_card_get_key: pare error!!!\n");
		return RET_ERR;
	}

	memset(send.data, 0, READER_BUF_SIZ);
	memcpy(send.data, reader->card_num, 8); 
	
	/* 1、PSAM通用DES初始化-(PSAM内部产生子密钥) */
	send.type    = READER_CONTACT_SAM1;
	send.cla	 = 0x80;
	send.cmd.ins = APDU_INIT_FOR_DESCRYPT;
	send.pa1.p1  = key_flag; 
	send.pa2.p2  = key_id;  
	send.len.lc  = 0x08; 
	send.le      = 0x00; 
	ret = reader_communication(reader, &send);
	if (((send.sw1 << 8) | send.sw2) != 0x9000) {
		debug("psam_card_get_key: DES init failed!!! errno: [%02x%02x]\n", \
			send.sw1, send.sw2);
		return ((send.sw1 << 8) | send.sw2);
	}

	/* 2、PSAM DES计算-获得过程密钥 */
	memset(send.data, 0, READER_BUF_SIZ);
	if (NORMAL_CPU_CARD == reader->card_type) { 
		memcpy(send.data, reader->key_data, reader->key_len); // CPU卡输入数据
	}
	else {
		strncpy((s8 *)send.data, CTCC_YJD_KEY_NAME, \
			strlen(CTCC_YJD_KEY_NAME));
	}
	send.type    = READER_CONTACT_SAM1;
	send.cla	 = 0x80;
	send.cmd.ins = APDU_DES_CRYPT;
	send.pa1.p1  = 0x00; 
	send.pa2.p2  = 0x00; 
	send.len.lc  = 0x08; 
	send.le      = 0x00; 
	ret = reader_communication(reader, &send);
	if (send.sw1 == 0x61) {
		ret = psam_apdu_get_response(reader, &send, send.sw2);
		if (ret) {
			debug("psam_card_get_key: get response failed!!!\n");
			return RET_ERR;
		}
	}
	else {
		debug("psam_card_get_key: DES calc failed!!!\n");
		return RET_ERR;
	}

	memcpy(reader->key_data, send.data, 8);
	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		debug("psam_card_get_key: %02X%02X%02X%02X%02X%02X%02X%02X\n", \
			send.data[0], send.data[1], send.data[2], send.data[3], \
			send.data[4], send.data[5], send.data[6], send.data[7]);
	}
	
	return RET_OK;
}


/**
  * 功能:  进入MF目录
  * 
  *
  * 返回值:
  * 	   
  **/

static s32 psam_apdu_select_mf(reader_op* reader, card_data *send)
{	
	s32 ret = 0;
	
	if (!reader || !send) {
		debug("psam_apdu_select_mf: para error!!!\n");
		return RET_ERR;
	}

	/* 选择MF */
	memset(send->data, 0, READER_BUF_SIZ);
	send->type    = READER_CONTACT_SAM1;
	send->cla     = 0x00;
	send->cmd.ins = APDU_SELECT_FILE;
	send->pa1.p1  = 0x00;
	send->pa2.p2  = 0x00;
	send->len.lc  = 2;
	send->le      = 0;
	send->data[0] = 0x3F;
	send->data[1] = 0x00;
	ret = reader_communication(reader, send);
	if (ret) {
		debug("psam_apdu_select_mf: select mf failed!!!\n");
		return RET_ERR;
	}

	return RET_OK;
}


/**
  * 功能:  PSAM返回结果数据
  * 
  *
  * 返回值:
  * 	   
  **/

s32 psam_apdu_get_response(reader_op *reader, card_data *send, u8 len)
{	
	if (!send) {
		debug("psam_apdu_get_response: para error!!!\n");
		return RET_ERR;
	}

	// 获取结果数据
	memset(send->data, 0, READER_BUF_SIZ);
	send->type	  = READER_CONTACT_SAM1;
	send->cla	  = 0x00;
	send->cmd.ins = APDU_GET_RESPONSE;
	send->pa1.p1  = 0x00;
	send->pa2.p2  = 0x00;
	send->len.lc  = 0;
	send->le      = len;

	reader_communication(reader, send);
	if (((send->sw1 << 8) | send->sw2) != 0x9000) {
		debug("mifare_card_get_response: get response failed!!! errno: [%02x%02x]\n", \
			send->sw1, send->sw2);
		return ((send->sw1 << 8) | send->sw2);
	}

	return RET_OK;
}


/**
  * 功能:  获取PSAM终端编号
  * 
  *
  * 返回值:
  * 	   
  **/

static s32 psam_apdu_read_binary(reader_op* reader, card_data *send)
{
	if (!reader || !send) {
		debug("psam_apdu_read_binary: para error!!!\n");
		return RET_ERR;
	}

	// 读②进制文件
	memset(send->data, 0, READER_BUF_SIZ);
	send->type    = READER_CONTACT_SAM1;
	send->cla     = 0x00;
	send->cmd.ins = APDU_READ_BINARY;
	send->pa1.p1  = 0x96;
	send->pa2.p2  = 0x00;
	send->len.lc  = 0;
	send->le      = 6;
	reader_communication(reader, send);
	if (((send->sw1 << 8) | send->sw2) != 0x9000) {
		debug("psam_apdu_read_binary: read binary failed!!! errno: [%02x%02x]\n", \
			send->sw1, send->sw2);
		return ((send->sw1 << 8) | send->sw2);
	}

	return RET_OK;
}


/**
  * 功能:  PSAM 进入应用目录
  * 
  *
  * 返回值:
  * 	   
  **/

s32 psam_apdu_select_dir(reader_op* reader, card_data *send)
{
	int ret = 0;
	
	if (!reader || !send) {
		debug("psam_apdu_select_dir: para error!!!\n");
		return RET_ERR;
	}

	// 进入应用目录
	send->type    = READER_CONTACT_SAM1;
	send->cla     = 0x00;
	send->cmd.ins = APDU_SELECT_FILE;
	send->pa1.p1  = 0x00;
	send->pa2.p2  = 0x00;
	send->len.lc  = strlen((s8 *)send->data);
	send->le      = 0;
	ret = reader_communication(reader, send);
	if (ret) {
		debug("psam_apdu_select_dir: read binary failed!!! errno: [%02x%02x]\n", \
			send->sw1, send->sw2);
		return RET_ERR;
	}

	return RET_OK;
}

/**
  * 功能:  PSAM 初始化
  * 
  *
  * 返回值:
  * 	   
  **/

s32 psam_card_init(reader_op* reader)
{
	s32 ret = 0;
	card_data send;

	if (!reader) {
		debug("psam_card_init para error!!!\n");
		return RET_ERR;
	}

	// 选择MF文件
	ret = psam_apdu_select_mf(reader, &send);
	if (send.sw1 == 0x61) {
		ret = psam_apdu_get_response(reader, &send, send.sw2);
		if (ret) {
			return RET_ERR;
		}
	}		
	else {
		return RET_ERR;
	}

	// 读取PSAM终端号
	ret = psam_apdu_read_binary(reader, &send);
	if (ret) {
		return RET_ERR;
	}
	memcpy(reader->terminal, send.data, 6);

	// 选择应用文件
	memset(send.data, 0, READER_BUF_SIZ);
	strncpy((s8 *)send.data, PSAM_APP_PATH, \
		strlen(PSAM_APP_PATH));
	ret = psam_apdu_select_dir(reader, &send);
	if (send.sw1 == 0x61) {
		ret = psam_apdu_get_response(reader, &send, send.sw2);
		if (ret) {
			return RET_ERR;
		}
	}	
	else {
		return RET_ERR;
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O0__) {
		debug("DEBUG_info: PSAM select file done\n");
	}

	return RET_OK;
}



